package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.model.enums.ReleaseStatus;
import com.atguigu.lease.web.admin.mapper.*;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.attr.AttrValueVo;
import com.atguigu.lease.web.admin.vo.graph.GraphVo;
import com.atguigu.lease.web.admin.vo.room.RoomDetailVo;
import com.atguigu.lease.web.admin.vo.room.RoomItemVo;
import com.atguigu.lease.web.admin.vo.room.RoomQueryVo;
import com.atguigu.lease.web.admin.vo.room.RoomSubmitVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author liubo
 * @description 针对表【room_info(房间信息表)】的数据库操作Service实现
 * @createDate 2023-07-24 15:48:00
 */
@Service
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo>
        implements RoomInfoService {


    @Resource
    RoomLeaseTermService roomLeaseTermService;
    @Resource
    RoomPaymentTypeService roomPaymentTypeService;

    @Resource
    RoomAttrValueService roomAttrValueService;

    @Resource
    RoomLabelService roomLabelService;

    @Resource
    RoomFacilityService roomFacilityService;

    @Resource
    GraphInfoService graphInfoService;

    @Resource
    RoomInfoMapper roomInfoMapper;

    @Resource
    ApartmentInfoMapper apartmentInfoMapper;

    @Resource
    GraphInfoMapper graphInfoMapper;

    @Resource
    AttrValueMapper attrValueMapper;
    @Resource
    FacilityInfoMapper facilityInfoMapper;

    @Resource
    LabelInfoMapper labelInfoMapper;

    @Resource
    PaymentTypeMapper paymentTypeMapper;

    @Resource
    LeaseTermMapper leaseTermMapper;

    @Resource
    RoomLeaseTermMapper roomLeaseTermMapper;

    @Resource
    RoomPaymentTypeMapper roomPaymentTypeMapper;

    @Resource
    RoomAttrValueMapper roomAttrValueMapper;

    @Resource
    RoomLabelMapper roomLabelMapper;

    @Resource
    RoomFacilityMapper roomFacilityMapper;

    @Override
    public void saveOrUpdateByVo(RoomSubmitVo roomSubmitVo) {
        // 1. 首先第一个我们需要判断roomSubmitVo中是否有id
        boolean existId = roomSubmitVo.getId() != null;
        // 2. 保存和更新roomInfo表中原本有的数据
        super.saveOrUpdate(roomSubmitVo);
        if (existId) { //更新的话就是说我们要将，原来关联表中的信息给删除，然后添加进去

            // - 房间-租期关系
            //  删除
            LambdaQueryWrapper<RoomLeaseTerm> roomLeaseTermLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomLeaseTermLambdaQueryWrapper.eq(RoomLeaseTerm::getRoomId, roomSubmitVo.getId());
            roomLeaseTermService.remove(roomLeaseTermLambdaQueryWrapper);


            // - 房间-支付方式关系
            // 删除
            LambdaQueryWrapper<RoomPaymentType> roomPaymentTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomPaymentTypeLambdaQueryWrapper.eq(RoomPaymentType::getRoomId, roomSubmitVo.getId());
            roomPaymentTypeService.remove(roomPaymentTypeLambdaQueryWrapper);


            // - 房间-属性值关系
            // 删除
            LambdaQueryWrapper<RoomAttrValue> roomAttrValueLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomAttrValueLambdaQueryWrapper.eq(RoomAttrValue::getRoomId, roomSubmitVo.getId());
            roomAttrValueService.remove(roomAttrValueLambdaQueryWrapper);


            // - 房间-标签关系
            //  删除
            LambdaQueryWrapper<RoomLabel> roomLabelLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomLabelLambdaQueryWrapper.eq(RoomLabel::getRoomId, roomSubmitVo.getId());
            roomLabelService.remove(roomLabelLambdaQueryWrapper);


            //  -房间配套关系
            //删除
            LambdaQueryWrapper<RoomFacility> roomFacilityLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roomFacilityLambdaQueryWrapper.eq(RoomFacility::getRoomId, roomSubmitVo.getId());
            roomFacilityService.remove(roomFacilityLambdaQueryWrapper);


            // -图片信息
            LambdaQueryWrapper<GraphInfo> graphInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            graphInfoLambdaQueryWrapper.eq(GraphInfo::getItemId, roomSubmitVo.getId()).eq(GraphInfo::getItemType, ItemType.ROOM);
            graphInfoService.remove(graphInfoLambdaQueryWrapper);


        }

        // TODO:在添加之前要判断数组是否为空，就比如一些人只希望改变一些数据其他数据是空的

        //  添加
        List<RoomLeaseTerm> roomLeaseTermList = roomSubmitVo.getLeaseTermIds().stream().map(TermId -> RoomLeaseTerm.builder()
                .roomId(roomSubmitVo.getId())
                .leaseTermId(TermId)
                .build()).toList();
        roomLeaseTermService.saveBatch(roomLeaseTermList);

        //  添加
        List<RoomPaymentType> roomPaymentTypeList = roomSubmitVo.getPaymentTypeIds().stream().map(typeId -> RoomPaymentType.builder()
                .roomId(roomSubmitVo.getId())
                .paymentTypeId(typeId)
                .build()).toList();
        roomPaymentTypeService.saveBatch(roomPaymentTypeList);

        // 添加
        List<RoomAttrValue> roomAttrValueList = roomSubmitVo.getAttrValueIds().stream().map(aId -> RoomAttrValue.builder()
                .roomId(roomSubmitVo.getId())
                .attrValueId(aId)
                .build()).toList();
        roomAttrValueService.saveBatch(roomAttrValueList);

        //  添加
        List<RoomLabel> roomLabelList = roomSubmitVo.getLabelInfoIds().stream().map(lId -> RoomLabel.builder()
                .roomId(roomSubmitVo.getId())
                .labelId(lId)
                .build()).toList();
        roomLabelService.saveBatch(roomLabelList);

        //添加
        List<RoomFacility> roomFacilityList = roomSubmitVo.getFacilityInfoIds().stream().map(fId -> RoomFacility
                .builder()
                .roomId(roomSubmitVo.getId())
                .facilityId(fId)
                .build()).toList();
        roomFacilityService.saveBatch(roomFacilityList);

        //添加
        List<GraphInfo> graphInfoList = roomSubmitVo.getGraphVoList().stream().map(graphVo -> GraphInfo.builder()
                .name(graphVo.getName())
                .url(graphVo.getUrl())
                .itemId(roomSubmitVo.getId())
                .itemType(ItemType.ROOM)
                .build()).toList();
        graphInfoService.saveBatch(graphInfoList);

    }

    @Override
    public Page<RoomItemVo> pageForVo(Page<RoomItemVo> page, RoomQueryVo queryVo) {
        Page<RoomItemVo> roomItemVoPage = roomInfoMapper.pageForVo(page, queryVo);

        return roomItemVoPage;
    }

    @Override
    @Transactional
    public RoomDetailVo getDetailById(Long id) {
        // 查roomInfo
        RoomInfo roomInfo = roomInfoMapper.selectById(id);
        // 查所属公寓信息
        ApartmentInfo apartmentInfo = apartmentInfoMapper.selectById(roomInfo.getApartmentId());
        // 图片列表
        //graphVoList
        List<GraphVo> graphVoList = graphInfoMapper.selectByRoomId(id, ItemType.ROOM);

        // 属性信息列表
        List<AttrValueVo> attrValueVoList = attrValueMapper.selectByRoomId(id);

        // 配套信息
        List<FacilityInfo> facilityInfoList = facilityInfoMapper.selectByRoomId(id);

        // 标签信息
        List<LabelInfo> labelInfoList = labelInfoMapper.selectByRoomId(id);

        // 支付方式
        List<PaymentType> paymentTypeList = paymentTypeMapper.selectByRoomId(id);


        // 可选租期列表
        List<LeaseTerm> leaseTermList = leaseTermMapper.selectByRoomId(id);

        RoomDetailVo roomDetailVo = RoomDetailVo.builder()
                .apartmentInfo(apartmentInfo)
                .attrValueVoList(attrValueVoList)
                .facilityInfoList(facilityInfoList)
                .labelInfoList(labelInfoList)
                .graphVoList(graphVoList)
                .leaseTermList(leaseTermList)
                .paymentTypeList(paymentTypeList)
                .build();

        BeanUtils.copyProperties(roomInfo, roomDetailVo);
        return roomDetailVo;
    }

    @Override
    public void removeByIdPro(Long id) {
        // 房间下面已经没有什么子集了，所以可以直接删除
        roomInfoMapper.deleteById(id);

        // 删除关联

        // - 房间租期
        LambdaQueryWrapper<RoomLeaseTerm> leaseTermLambdaQueryWrapper = new LambdaQueryWrapper<>();
        leaseTermLambdaQueryWrapper.eq(RoomLeaseTerm::getRoomId, id);
        roomLeaseTermMapper.delete(leaseTermLambdaQueryWrapper);

        // - 房间支付
        LambdaQueryWrapper<RoomPaymentType> roomPaymentTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roomPaymentTypeLambdaQueryWrapper.eq(RoomPaymentType::getRoomId, id);
        roomPaymentTypeMapper.delete(roomPaymentTypeLambdaQueryWrapper);

        // - 房间属性
        LambdaQueryWrapper<RoomAttrValue> roomAttrValueLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roomAttrValueLambdaQueryWrapper.eq(RoomAttrValue::getRoomId, id);
        roomAttrValueMapper.delete(roomAttrValueLambdaQueryWrapper);


        // - 房间配套
        LambdaQueryWrapper<RoomFacility> roomFacilityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roomFacilityLambdaQueryWrapper.eq(RoomFacility::getRoomId, id);
        roomFacilityMapper.delete(roomFacilityLambdaQueryWrapper);

        // - 房间标签
        LambdaQueryWrapper<RoomLabel> roomLabelLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roomLabelLambdaQueryWrapper.eq(RoomLabel::getRoomId, id);
        roomLabelMapper.delete(roomLabelLambdaQueryWrapper);

        //图片信息
        LambdaQueryWrapper<GraphInfo> graphInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        graphInfoLambdaQueryWrapper.eq(GraphInfo::getItemId, id).eq(GraphInfo::getItemType,ItemType.ROOM);
        graphInfoMapper.delete(graphInfoLambdaQueryWrapper);


    }

    @Override
    public void updateReleaseStatusById(Long id, ReleaseStatus status) {
        LambdaUpdateWrapper<RoomInfo> roomInfoLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        roomInfoLambdaUpdateWrapper.eq(RoomInfo::getId,id).set(RoomInfo::getIsRelease,status);
        super.update(roomInfoLambdaUpdateWrapper);
    }
}




